package com.sangmo.fts.process.storage.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.plugin.dataview.crud.service.BaseViewService;
import com.sangmo.boot.framework.plugin.dataview.data.IDataViewRepo;
import com.sangmo.fts.common.authority.service.AuthorityEntityService;
import com.sangmo.fts.common.utils.RandomUtils;
import com.sangmo.fts.process.storage.interfaces.CsfWaybillCreation;
import com.sangmo.fts.process.storage.model.CsfAgreement;
import com.sangmo.fts.process.storage.model.CsfContract;
import com.sangmo.fts.process.storage.model.CsfContractItem;
import com.sangmo.fts.process.storage.model.CsfDraft;
import com.sangmo.fts.process.storage.model.CsfLoan;
import com.sangmo.fts.process.storage.model.CsfWaybill;
import com.sangmo.fts.process.storage.model.CsfWaybillItem;
import com.sangmo.fts.process.storage.repo.CsfWaybillItemRepo;
import com.sangmo.fts.process.storage.repo.CsfWaybillRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class CsfWaybillEntityService extends AuthorityEntityService<CsfWaybill> {

    @Autowired
    private CsfWaybillRepo csfWaybillRepo;

    @Autowired
    private CsfDraftService csfDraftService;

    @Autowired
    private CsfContractService csfContractService;

    @Autowired
    private CsfLoanService csfLoanService;

    @Autowired
    private CsfAgreementService csfAgreementService;

    @Autowired
    private CsfWaybillItemEntityService csfWaybillItemEntityService;

    @Override
    protected IDataViewRepo<CsfWaybill> getRepo() {
        return csfWaybillRepo;
    }

    @Override
    protected void onCreate(CsfWaybill entity, Object bo) {
        super.onCreate(entity, bo);
        entity.setCode(RandomUtils.generateRandomNum(12));
        CsfWaybillCreation creation = (CsfWaybillCreation) bo;
        CsfDraft draft = csfDraftService.get(creation.getDraftId());
        CsfLoan loan = csfLoanService.get(draft.getLoanId());
        CsfContract contract = csfContractService.get(loan.getContractId());
        entity.setContractId(contract.getId());
        entity.setShipper(contract.getSellerId());
        CsfAgreement agreement = csfAgreementService.findByContractId(contract.getId());
        entity.setConsignee(agreement.getStorageId());
        entity.setAgreementId(agreement.getId());
    }

    @Override
    protected void afterCreated(CsfWaybill entity, Object bo) {
        super.afterCreated(entity, bo);
        CsfWaybillCreation creation = (CsfWaybillCreation) bo;
        List<CsfContractItem> contractItems = csfContractService.listItemsByContractId(entity.getContractId());
        List<CsfWaybillItem> waybillItems = buildCsfWaybillItems(entity.getId(), contractItems);
        csfWaybillItemEntityService.saveAll(waybillItems);
    }


    private List<CsfWaybillItem> buildCsfWaybillItems(Long waybillId, List<CsfContractItem> contractItems) {
        List<CsfWaybillItem> waybillItems = new ArrayList<>();
        for (CsfContractItem contractItem : contractItems) {
            CsfWaybillItem item = CsfWaybillItem.fromContractItem(contractItem);
            item.setWaybillId(waybillId);
            waybillItems.add(item);
        }
        return waybillItems;
    }

    @Override
    protected void onDelete(CsfWaybill entity) {
        super.onDelete(entity);
        if (!CsfWaybill.States.PENDING.equals(entity.getState())) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.csfWaybill.remove.permit.disabled");
        }
    }
}
